home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / Reference / Amiga_Mail_Vol2 / Archives / Plain / so91.lha / Pattern / pattern.txt < prev    next >
Encoding:
Text File  |  1991-10-23  |  7.1 KB  |  162 lines

  1. (c)  Copyright 1991 Commodore-Amiga, Inc.   All rights reserved.
  2. The information contained herein is subject to change without notice,
  3. and is provided "as is" without warranty of any kind, either expressed
  4. or implied.  The entire risk as to the use of this information is
  5. assumed by the user.
  6.  
  7.  
  8. Using the AmigaDOS Pattern Matching Functions
  9.  
  10.  
  11.  
  12.  
  13. by Ewout Walraven
  14.  
  15.  
  16. One of the additions made to dos.library for release 2.0 is a series of
  17. functions to do standard pattern matching.  Using a set of standard of
  18. string matching tokens, any application can use these functions to test if
  19. a particular string matches a pattern.  The Amiga OS uses these functions
  20. for processing file name strings for its new directory scanning functions.
  21.  
  22. These functions can be used in every circumstance where you would like to
  23. enable the user to enter a pattern to indicate more than one target string.
  24. Using these functions not only makes it unnecessary to implement your own
  25. pattern matching routines, but by using the familiar DOS pattern tokens in
  26. your application, it is easier for the user to learn how to use your
  27. application.
  28.  
  29.  
  30. Patterns
  31.  
  32. An AmigaDOS pattern matching string is a combination of alphanumeric
  33. characters and a series of special token characters.  These token
  34. characters are part of the ASCII character set and they denote such things
  35. as string matching wildcards, string repetitions, and string negation.
  36. Pattern matching strings can use parentheses to delimit pattern matching
  37. substrings.
  38.  
  39. ?    The question mark matches any single character.  For
  40.     example, the pattern matching string ``A?B'' matches any string that is
  41.     three letters long, that starts with an ``A'' and end swith a ``B''.
  42.  
  43.  
  44.  
  45. #    The number sign matches strings containing one or more
  46.     repetitions of the expression that immediately follows the # in the pattern
  47.     matching string.  For example, the pattern matching string ``#A'' matches
  48.     any string that consists of one or more of the ``A'' character.  The
  49.     pattern matching string ``#?'' matches any non-NULL string.  The # can
  50.     apply to entire substrings delimited by parentheses.  For example, the
  51.     pattern string ``#(AB)'' matches any string consisting of one or more
  52.     repetitions of the substring ``AB'' (AB, ABAB, ABABAB...).
  53.  
  54. %    Matches the NULL string.
  55.  
  56. |    This is the OR symbol.  This matches strings that contain the
  57.     expressions on either side of the OR sign.  The expressions and the OR
  58.     symbol need to be enclosed in parentheses.  For example, the pattern
  59.     matching string ``(A|B)'' matches the string ``A'' or the string ``B''.
  60.     The pattern matching string A(B|%|C) matches the strings ``AB'', ``A'', and
  61.     ``AC''.
  62.  
  63. ~    The tilde negates the expression that follows it.  All strings that
  64.     do not match the expression that follows the tilde will match the
  65.     expression with the tilde.  For example, the pattern matching string
  66.     ``~(#?.info)'' matches any string that does not match the string
  67.     ``#?.info'' (does not end with the substring ``.info'').
  68.  
  69. *    The star is provided as an synonym to "#?".  This is an option
  70.     which can be turned on.  Note that the star can not be used by itself on
  71.     all non-FileSystem devices, like a logical device name assigned to a
  72.     directory on a file system.  For example:
  73.             Assign A: dh0:tmp
  74.             cd a:
  75.             list *
  76.     will produce an error.  The SetStar.c example at the end of this article is
  77.     a small stand alone utility to turn this option on and off.
  78.  
  79. []    All characters within brackets indicate a character class.  Any
  80.     character in the character class qualifies.  Within a character class, a
  81.     character range can be indicated by specified the start and stop character,
  82.     separated with a minus sign.  Note that character classes are case
  83.     sensitive.  If character classes are to be used in a case insensitive form,
  84.     they should be translated to uppercase.  Here are some example:
  85.             [ACF]#?     matches strings starting with `A', `C', or `F'
  86.             [A-D]#?        matches strings starting with `A', `B', `C', or `D'
  87.             [~ACF]#?         matches strings not starting with `A', `C', or `F'
  88.  
  89.  
  90. '    The quote character neutralizes the special meaning of a special
  91.     character.  Here are some examples:
  92.             '#'? matches only the literal string ``#?''
  93.             '?(A|B|C|%)'# matches the literal strings
  94.                                   ``?#'', ``?A#'', ``?B#'', ``?C#''
  95.             '' matches '
  96.  
  97. ()    Parentheses group special characters.  The expression within the
  98.     parentheses is a subpattern.
  99.  
  100.  
  101. Parsing
  102.  
  103. When you want to use a string as an AmigaDOS wildcard pattern, the system
  104. must first parse it.  The system builds a token string which the system
  105. uses to match strings.  There are two functions in dos.library to parse
  106. pattern matching strings:
  107.  
  108. LONG ParsePattern(UBYTE *SourcePattern,
  109.                   UBYTE *MyDestination,
  110.                   LONG DestLength);
  111. LONG ParsePatternNoCase(UBYTE *SourcePattern,
  112.                         UBYTE *MyDestination,
  113.                         LONG DestLength);
  114.  
  115. The ParsePattern() function creates a case sensitive token string, whereas
  116. the ParsePatternNoCase() functions creates a case insensitive token string.
  117. Both functions require a pointer to a destination buffer (MyDestination in
  118. the above prototype) to place the tokenized string in.  Since every
  119. character in the pattern can be expanded to two tokens (3 in one case),
  120. this buffer should be at twice as as large as the original pattern plus 2
  121. bytes.  As a general rule, allocating a buffer three times the size of the
  122. pattern will hold all patterns.  The third argument, DestLength, indicates
  123. the size of the destination buffer provided.  These functions will returns
  124. one of three values:
  125.  
  126. -1  if there is an error (if the buffer is too small to hold all the tokens
  127. or the source string contains an invalid pattern),
  128.  
  129. 1   if the wildcard pattern was parsed successfully and the pattern
  130. contains one of the special token characters.
  131.  
  132. 0   if the wildcard pattern was parsed successfully and pattern contained
  133. only alphanumeric characters (no special token characters)
  134.  
  135.  
  136.  
  137.  
  138. Matching
  139.  
  140. Once a pattern is parsed, it can be compared to a string using either the
  141. case sensitive MatchPattern() or the case insensitive MatchPatternNoCase()
  142. functions.  These functions have the following synopsis:
  143.  
  144. BOOL MatchPattern(UBYTE *mytokenpattern, UBYTE *mystring);
  145. BOOL MatchPatternNoCase (UBYTE *mytokenpattern, UBYTE *mystring);
  146.  
  147. These functions will compare the wildcard pattern string, mytokenpattern
  148. (created by ParsePattern/NoCase()), to mystring.  If mystring matches the
  149. pattern in mytokenpattern, these routines return TRUE, otherwise they
  150. return FALSE.
  151.  
  152. Because these routines are recursive, they can use a lot of stack space,
  153. although they will not use more than 1500 bytes of stack space.  Make sure
  154. the stack space is at least 1500 bytes before calling these routines.
  155.  
  156. In V36, these routines did not perform any stack checking.  This was added
  157. in V37.  If either of these functions detect a stack overflow, they will
  158. return 0 and IoErr() will return ERROR_TOO_MANY_LEVELS.  If IoErr() returns
  159. 0, there was simply no match.  The Pattern.c example at the end of this
  160. article shows how to use the parse and match functions and allows you to
  161. test and experiment with patterns.
  162.